package com.yqb.study.config.multidatasource;

import java.sql.SQLException;
import java.util.HashMap;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import com.alibaba.druid.pool.DruidDataSource;
import com.baomidou.mybatisplus.plugins.PaginationInterceptor;
import com.yqb.study.common.multidatasource.DynamicDataSource;
import com.yqb.study.constant.multidatasource.DataSourceEnum;

/**
 * MybatisPlus配置
 * 
 * 1.如果配置文件muti-datasource-open为false，不管使用注解DataSource还是不使用，使用的数据源都是Master的Druid
 * 2.如果配置文件muti-datasource-open为true，使用DynamicDataSource维护多数据源，其中保存"数据源名称"和"数据源Druid"的Map
 *   使用AOP拦截注解DataSource，按照该注解中的名字切换数据源Druid
 */
@Configuration
@EnableTransactionManagement(order = 5)// 由于引入多数据源，所以让spring事务的aop要在多数据源切换aop的后面
@MapperScan(basePackages = {"com.yqb.study.modular.dao.mysql", "com.yqb.study.modular.persistence.dao"})// @MapperScan 扫描 Mapper 接口并容器管理
public class MybatisPlusConfig {

	@Autowired
	private DruidProperties druidProperties;
	
    @Autowired
    MasterDataSourceProperties masterDataSourceProperties;

    @Autowired
    ClusterDataSourceProperties clusterDataSourceProperties;
    
    /**
     * Master数据源
     */
    private DruidDataSource dataSourceMaster(){
        DruidDataSource dataSource = new DruidDataSource();
        druidProperties.config(dataSource);
        masterDataSourceProperties.config(dataSource);
        return dataSource;
    }    
 
    /**
     * Cluster数据源
     */
    private DruidDataSource dataSourceCluster() {
        DruidDataSource dataSource = new DruidDataSource();
        druidProperties.config(dataSource);
        clusterDataSourceProperties.config(dataSource);
        return dataSource;
    }

    /**
     * 单数据源连接池配置
     */
    @Bean
    @ConditionalOnProperty(prefix = "springbootstudy", name = "muti-datasource-open", havingValue = "false")
    public DruidDataSource singleDatasource() {
        return dataSourceMaster();
    }

    /**
     * 多数据源连接池配置,与配置文件application.yml中使用数据源注意保持同步
     */
    @Bean
    @ConditionalOnProperty(prefix = "springbootstudy", name = "muti-datasource-open", havingValue = "true")
    public DynamicDataSource mutiDataSource() {

        DruidDataSource dataSourceMaster = dataSourceMaster();
        DruidDataSource dataSourceCluster = dataSourceCluster();

		try {
			dataSourceMaster.init();
			dataSourceCluster.init();
		} catch (SQLException sql) {
			sql.printStackTrace();
		}

        // DynamicDataSource类继承AbstractRoutingDataSource，Spring boot提供了AbstractRoutingDataSource根据用户定义的规则选择当前的数据库
        DynamicDataSource dynamicDataSource = new DynamicDataSource();
        HashMap<Object, Object> hashMap = new HashMap();
        hashMap.put(DataSourceEnum.MASTERDB.getNameEn(), dataSourceMaster);
        hashMap.put(DataSourceEnum.CLUSTERDB.getNameEn(), dataSourceCluster);
        // 保存"数据源名称"和"数据源Druid"的Map
        dynamicDataSource.setTargetDataSources(hashMap);
        // 默认使用Master
        dynamicDataSource.setDefaultTargetDataSource(dataSourceMaster);
        return dynamicDataSource;
    }

    /**
     * mybatis-plus分页插件
     */
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        return new PaginationInterceptor();
    }

//    /**
//     * 数据范围mybatis插件
//     */
//    @Bean
//    public DataScopeInterceptor dataScopeInterceptor() {
//        return new DataScopeInterceptor();
//    }
}


///** 
// * 自定义事务 
// * Created by huguoju on 2016/12/29. 
// */  
//@Configuration  
//@EnableTransactionManagement  
//@Slf4j  
//public class DataSourceTransactionManager extends DataSourceTransactionManagerAutoConfiguration {  
//    /** 
//     * 自定义事务 
//     * MyBatis自动参与到spring事务管理中，无需额外配置，只要org.mybatis.spring.SqlSessionFactoryBean引用的数据源与DataSourceTransactionManager引用的数据源一致即可，否则事务管理会不起作用。 
//     * @return 
//     */  
//    @Resource(name = "writeDataSource")  
//    private DataSource dataSource;  
//    @Bean(name = "transactionManager")  
//    public org.springframework.jdbc.datasource.DataSourceTransactionManager transactionManagers() {  
//        log.info("-------------------- transactionManager init ---------------------");  
//        return new org.springframework.jdbc.datasource.DataSourceTransactionManager(dataSource);  
//    }  
//}  
